/**
 * storage 缓存处理工具
 *
 * 使用说明：
 *  引入对象
 *    import { Local, Session } from '@/utils/storage'
 *  读取属性
 *    Local.get('key')
 *  写入属性
 *    Local.set('key', Object || Array || any)
 *  移除属性
 *    Local.remove('key')
 *  是否存在该属性
 *    Local.has('key')
 *
 * Session用法一致
 *
 */

class Storage {
  drive: any
  get(key: string) {
    let result = this.drive.getItem(key)
    if (result) {
      let data = deserialize(result)

      // if (Math.floor(+new Date() / 1000) >= data.expires && data.expires !== -1) {
      //   data.data = def
      //   this.remove(key)
      // }

      return data
    } else {
      return undefined
    }
  }

  set(key: string, val: any, expires = -1) {
    try {
      if (val === undefined) {
        return this.remove(key)
      }

      // if (typeof expires === 'number' && expires >= 0) {
      //   expires = Math.floor(+new Date() / 1000) + expires
      // } else {
      //   expires = -1
      // }

      // let data = {
      //   data: val,
      //   expires
      // }

      this.drive.setItem(key, serialize(val))
    } catch (e) {
      console.log('Local Storage is full, Please empty data')
    }
    return val
  }

  has(key: any) {
    return this.get(key) !== undefined
  }

  remove(key: any) {
    this.drive.removeItem(key)
  }

  clear() {
    this.drive.clear()
  }

  get size() {
    let total = 0
    for (let x in this.drive) {
      // Value is multiplied by 2 due to data being stored in `utf-16` format, which requires twice the space.
      let amount = this.drive[x].length * 2
      if (!isNaN(amount) && Object.prototype.hasOwnProperty.call(this.drive, x)) {
        total += amount
      }
    }
    return total.toFixed(2)
  }
}

class LocalStorage extends Storage {
  declare drive: globalThis.Storage
  constructor() {
    super()
    this.drive = window.localStorage
  }
}

class SessionStorage extends Storage {
  declare drive: globalThis.Storage
  constructor() {
    super()
    this.drive = window.sessionStorage
  }
}

export const Local = new LocalStorage()
export const Session = new SessionStorage()

function serialize(val: any) {
  return JSON.stringify(val)
}

function deserialize(val: string) {
  if (typeof val !== 'string') {
    return undefined
  }
  try {
    return JSON.parse(val)
  } catch (e) {
    return val || undefined
  }
}
